package com.bdy.lm.taximanager.model;

import com.bdy.lm.taximanager.app.MyApp;
import com.bdy.lm.taximanager.util.TimeUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/8/26.
 */

public class MessagePackaging {

    private byte[] messageHead = new byte[13], messageEnd = new byte[2];
    private byte[] messageBodyByte;
    private byte[] messagePackageByte;
    private Map<String, Object> heartBitMessagePackageMap = new HashMap<String, Object>();
    private Map<String, Object> locationMessagePackageMap = new HashMap<String, Object>();
    private Map<String, Object> responseQueryLocationMessage = new HashMap<String, Object>();
    private Map<String, Object> loginMessagePackageMap = new HashMap<String, Object>();
    private Map<String, Object> messagePackageMap = new HashMap<String, Object>();
    private static volatile int messageSerial = 0;
    private byte[] messageID = new byte[2];
    private int messageId;

    public MessagePackaging(int ID) {
        messageId = ID;
        messageID[0] = (byte) ((0xff00 & ID) >> 8);
        messageID[1] = (byte) (0xff00 & ID);
    }

    public void setMessageHead() {
        messageHead[0] = 0x7e;
        messageHead[1] = messageID[0];
        messageHead[2] = messageID[1];
        messageHead[5] = (byte) MyApp.ISUFlag_1;
        messageHead[6] = (byte) MyApp.ISUFlag_company_2;
        messageHead[7] = (byte) MyApp.ISUFlag_device_3;
        messageHead[8] = (byte) ((MyApp.ISUFlag_serialNum_4 & 0xff0000) >> 16);
        messageHead[9] = (byte) ((MyApp.ISUFlag_serialNum_4 & 0x00ff00) >> 8);
        messageHead[10] = (byte) (MyApp.ISUFlag_serialNum_4 & 0x0000ff);
        //Log.d("messageHead", Arrays.toString(messageHead));
    }

    public void setMessageBodyByte(byte[] messageBodyByte) {
        this.messageBodyByte = messageBodyByte;
    }

    public byte[] getMessagePackageByte() {
        setMessageHead();
        messageSerial++;
        byte[] message;
        if (messageBodyByte == null) {
            message = messageHead;
        } else {
            message = concat(messageHead, messageBodyByte);
        }
        messageEnd[0] = xor(message);
        messageEnd[1] = 0x7e;
        messagePackageByte = concat(message, messageEnd);
        messagePackageByte[3] = (byte) ((0xff00 & messagePackageByte.length) >> 8);
        messagePackageByte[4] = (byte) (0x00ff & messagePackageByte.length);
        messagePackageByte[11] = (byte) ((messageSerial & 0xff00) >> 8);
        messagePackageByte[12] = (byte) (messageSerial & 0x00ff);
        return messagePackageByte;
    }
    public Map<String, Object> getSignOutMessageMap(String id) {
        loginMessagePackageMap = constructMessagePackageMapShell();
        loginMessagePackageMap.putAll(MyApp.locationMessageBody.getLocationMessageMap());
        loginMessagePackageMap.put("ICID", id);
        loginMessagePackageMap.put("state", "signOut");
        loginMessagePackageMap.put("loginOutTime", TimeUtils.getStampTime());
        return loginMessagePackageMap;
    }
    public Map<String, Object> getLoginMessageMap(String ICID) {
        loginMessagePackageMap = constructMessagePackageMapShell();
        loginMessagePackageMap.putAll(MyApp.locationMessageBody.getLocationMessageMap());
        loginMessagePackageMap.put("ICID", ICID);
        loginMessagePackageMap.put("state", "login");
        loginMessagePackageMap.put("loginOutTime", TimeUtils.getStampTime());
        return loginMessagePackageMap;
    }

    public Map<String, Object> getHeartBitMessagePackageMap() {
        heartBitMessagePackageMap = constructMessagePackageMapShell();
        heartBitMessagePackageMap.put("reportTime", TimeUtils.getStampTime());
        heartBitMessagePackageMap.put("runState", MyApp.runState);
        heartBitMessagePackageMap.put("ICID", DriverInfo.getDriverInfo().getICID());
        return heartBitMessagePackageMap;
    }

    public Map<String, Object> getTransactionMessagePackageMap(Map<String, Object> tran) {
        heartBitMessagePackageMap = constructMessagePackageMapShell();
        heartBitMessagePackageMap.put("ICID", DriverInfo.getDriverInfo().getICID());
        heartBitMessagePackageMap.putAll(tran);
        return heartBitMessagePackageMap;
    }

    public Map<String, Object> getIsExecuteMessagePackageMap(String publishTime) {
        heartBitMessagePackageMap = constructMessagePackageMapShell();
        heartBitMessagePackageMap.put("publishTime", publishTime);
        return heartBitMessagePackageMap;
    }

    public Map<String, Object> getLocationMessagePackageMap() {
        locationMessagePackageMap = MyApp.locationMessageBody.getLocationMessageMap();
        locationMessagePackageMap.putAll(constructMessagePackageMapShell());
        return locationMessagePackageMap;
    }

    public Map<String, Object> getFareInfoMap() {
        Map<String, Object> tmp = constructMessagePackageMapShell();
        tmp.put("areaId", DriverInfo.getDriverInfo().getAreaId());
        return tmp;
    }

    public Map<String, Object> getQueryStandRouteMap(String num) {
        Map<String, Object> tmp = constructMessagePackageMapShell();
        tmp.put("standardRouteNum", num);
        return tmp;
    }

    public Map<String, Object> getReportSCarMeasureMap(CarMeasure carMeasure, List<LocationTrack> locationTracks) {
        Map<String, Object> tmp = constructMessagePackageMapShell();
        tmp.put("carMeasure", carMeasure);
        tmp.put("locationTracks", locationTracks);
        tmp.put("verifyTime", TimeUtils.getStampTimeString());
        return tmp;
    }

    public Map<String, Object> getResponseQueryLocationMessage(int responseSerial, byte result) {
        byte[] bytes = new byte[3];
        bytes[0] = (byte) ((responseSerial & 0xff00) >> 8);
        bytes[1] = (byte) (responseSerial & 0x00ff);
        setMessageBodyByte(bytes);
        responseQueryLocationMessage = constructMessagePackageMapShell();
        responseQueryLocationMessage.put("responseSerialNum", responseSerial);
        responseQueryLocationMessage.putAll(getLocationMessagePackageMap());
        return responseQueryLocationMessage;
    }

    public Map<String, Object> getGeneralResponseMessage(int responseSerial, int responseID, byte result) {
        byte[] bytes = new byte[5];
        bytes[0] = (byte) ((responseSerial & 0xff00) >> 8);
        bytes[1] = (byte) (responseSerial & 0x00ff);
        bytes[2] = (byte) ((responseID & 0xff00) >> 8);
        bytes[3] = (byte) (responseID & 0x00ff);
        bytes[4] = result;
        setMessageBodyByte(bytes);
        responseQueryLocationMessage = constructMessagePackageMapShell();
        responseQueryLocationMessage.put("responseSerialNum", responseSerial);
        responseQueryLocationMessage.put("responseID", responseID);
        responseQueryLocationMessage.put("result", result);
        return responseQueryLocationMessage;
    }

    private Map<String, Object> constructMessagePackageMapShell() {
        byte[] bytes = getMessagePackageByte();
        messagePackageMap.put("flagBitBegin", 0x7e);
        messagePackageMap.put("messageID", messageId);
        messagePackageMap.put("messageSize", (bytes[3] << 8) + bytes[4]);
        messagePackageMap.put("ISUFlag", MyApp.ISUFlag);
//        messagePackageMap.put("ISUFlag_1", bytes[5]);
//        messagePackageMap.put("ISUFlag_company_2", bytes[6]);
//        messagePackageMap.put("ISUFlag_device_3", bytes[7]);
//        messagePackageMap.put("ISUFlag_serialNum_4", MyApp.ISUFlag_serialNum_4);
        //System.out.println("MyApp.ISUFlag_serialNum_4:" + MyApp.ISUFlag_serialNum_4);
        messagePackageMap.put("messageSerialNum", messageSerial);
        messagePackageMap.put("checkCode", messageEnd[0]);
        messagePackageMap.put("flagBitEnd", messageEnd[1]);
        return messagePackageMap;
    }

    private byte[] concat(byte[] a, byte[] b) {
        byte[] c = new byte[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }

    //从第一位开始异或
    private byte xor(byte[] msg) {
        byte result = msg[0];
        int i = 1;
        while (i < msg.length) {
            result = (byte) (result ^ msg[i]);
            i++;
        }
        return result;
    }
}
